package com.example.designpattern.creational.builder;

/**
 * 建造者模式用于创建过程稳定，但配置多变的对象。在《设计模式》一书中的定义是：
 * 将一个复杂的构建与其表示相分离，使得同样的构建过程可以创建不同的表示。
 * <p>
 * 经典的“建造者-指挥者”模式现在已经不太常用了，现在建造者模式主要用来通过链式调用生成不同的配置。
 * 比如我们要制作一杯珍珠奶茶。它的制作过程是稳定的，除了必须要知道奶茶的种类和规格外，是否加珍珠和是否加冰是可选的。
 * 使用建造者模式表示如下：
 * <p>
 * 本质上就是定制化创建对象，定制化构建过程
 * <p>
 * 使用建造者模式的好处是不用担心忘了指定某个配置，保证了构建过程是稳定的。
 * 在 OkHttp、Retrofit 等著名框架的源码中都使用到了建造者模式。
 */
public class MilkTea {
    private String type;
    private String size;
    private boolean pearl;
    private boolean ice;

    /**
     * 可以看到，我们将 MilkTea 的构造方法设置为私有的，所以外部不能通过 new 构建出 MilkTea 实例，只能通过 Builder 构建。
     * 对于必须配置的属性，通过 Builder 的构造方法传入，可选的属性通过 Builder 的链式调用方法传入，
     * 如果不配置，将使用默认配置，也就是中杯、加珍珠、不加冰。
     */
    private MilkTea() {
    }

    private MilkTea(Builder builder) {
        this.type = builder.type;
        this.size = builder.size;
        this.pearl = builder.pearl;
        this.ice = builder.ice;
    }

    public String getType() {
        return type;
    }

    public String getSize() {
        return size;
    }

    public boolean isPearl() {
        return pearl;
    }

    public boolean isIce() {
        return ice;
    }

    public static class Builder {

        private final String type;
        private String size = "中杯";
        private boolean pearl = true;
        private boolean ice = false;

        public Builder(String type) {
            this.type = type;
        }

        public Builder size(String size) {
            this.size = size;
            return this;
        }

        public Builder pearl(boolean pearl) {
            this.pearl = pearl;
            return this;
        }

        public Builder ice(boolean cold) {
            this.ice = cold;
            return this;
        }

        public MilkTea build() {
            return new MilkTea(this);
        }
    }
}

